﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;

namespace Brain.Editor
{
    public class ContentProject : IBrainSonSerialiable
    {
        public List<ContentProjectFile> Files;

        public string Name;

        public bool ShouldSerialize { get; set; }

        public ContentProject( string name, Stream xnaContentProjectStream)
        {
            this.Name = name;
            Files = new List<ContentProjectFile>();
            ReadXNAContentProject(xnaContentProjectStream);
            ShouldSerialize = true;
        }
        public ContentProject(string name)
        {
            this.Name = name;
            Files = new List<ContentProjectFile>();
            ShouldSerialize = true;
        }
        public ContentProject()
        {
            Files = new List<ContentProjectFile>();
            ShouldSerialize = true;
        }

        private void ReadXNAContentProject(Stream str)
        {
#if !SILVERLIGHT
            XmlReader reader = XmlReader.Create(str);

            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "Project")
                    {
                        while (reader.Read())
                        {
                            if (reader.Name == "ItemGroup")
                            {
                                while (reader.Read())
                                {
                                    if (reader.Name == "Compile")
                                    {
                                        ContentProjectFile file = new ContentProjectFile();
                                        file.Project = this;
                                        string s = reader.GetAttribute("Include");
                                        file.RelativePath = s;
                                        file.FileExtension = Path.GetExtension(s);
                                        while (reader.Read() && reader.NodeType != XmlNodeType.EndElement)
                                        {
                                            if (reader.NodeType != XmlNodeType.Whitespace)
                                            {
                                                string att = reader.Name;
                                                string value = reader.ReadElementContentAsString();

                                                string lower = att.ToLower();
                                                if (lower == "name")
                                                {
                                                    file.Name = value;
                                                }
                                                else if (lower == "importer")
                                                {
                                                    file.Importer = value;
                                                }
                                                else if (lower == "processor")
                                                {
                                                    file.Processor = value;
                                                }
                                                else if (lower.StartsWith("processorparameters_"))
                                                {
                                                    if (file.ProcessorParameters == null)
                                                    {
                                                        file.ProcessorParameters = new List<NameValue>();
                                                    }
                                                    file.ProcessorParameters.Add(
                                                        new NameValue(att.Remove(0, 20),
                                                            value));
                                                }
                                                else if (lower.StartsWith("importerparameters_"))
                                                {
                                                    if (file.ImporterParameters == null)
                                                    {
                                                        file.ImporterParameters = new List<NameValue>();
                                                    }
                                                    file.ImporterParameters.Add(
                                                        new NameValue(att.Remove(0, 20),
                                                            value));
                                                }
                                            }
                                        }
                                        Files.Add(file);
                                    }
                                }
                            }
                        }
                    }
                }
            }
#endif
        }

        public void SerializeData(SerializationData parentData, int index)
        {
            parentData.AddData("ContentProject.Name", this.Name, index);

            parentData.AddData("ContentProject.Files", Files.Count, index);
            for (int i = 0; i < Files.Count; i++)
            {
                ContentProjectFile file = Files[i];

                parentData.AddData("ContentProjectFile.FileExtension" + i, file.FileExtension, index);
                parentData.AddData("ContentProjectFile.Importer" + i, file.Importer, index);
                parentData.AddData("ContentProjectFile.SaveOnEditorSave" + i, file.SaveOnEditorSave, index);

                if (file.ImporterParameters != null)
                {
                    parentData.AddData("ContentProjectFile.ImporterParameters" + i, file.ImporterParameters.Count, index);
                    for (int x = 0; x < file.ImporterParameters.Count; x++)
                    {
                        NameValue value = file.ImporterParameters[x];
                        parentData.AddData("ContentProjectFile.ImporterParameter.Name" + i + ":" + x, value.Name, index);
                        parentData.AddData("ContentProjectFile.ImporterParameter.Value" + i + ":" + x, value.Value, index);
                    }
                }

                parentData.AddData("ContentProjectFile.NeedsProcessing" + i, file.NeedsProcessing, index);
                parentData.AddData("ContentProjectFile.Name" + i, file.Name, index);
                parentData.AddData("ContentProjectFile.ProcessedPath" + i, file.ProcessedPath, index);
                parentData.AddData("ContentProjectFile.Processor" + i, file.Processor, index);

                if (file.ProcessorParameters != null)
                {
                    parentData.AddData("ContentProjectFile.ProcessorParameters" + i, file.ImporterParameters.Count, index);
                    for (int x = 0; x < file.ProcessorParameters.Count; x++)
                    {
                        NameValue value = file.ProcessorParameters[x];
                        parentData.AddData("ContentProjectFile.ProcessorParameter.Name" + i + ":" + x, value.Name, index);
                        parentData.AddData("ContentProjectFile.ProcessorParameter.Value" + i + ":" + x, value.Value, index);
                    }
                }
                parentData.AddData("ContentProjectFile.RelativePath" + i, file.RelativePath, index);
            }
        }

        public void DeserializeData(SerializationData parentData, int index)
        {
            this.Name = parentData.GetData<string>("ContentProject.Name", index);

            int files = parentData.GetData<int>("ContentProject.Files", index);
            for (int i = 0; i < files; i++)
            {
                ContentProjectFile file = new ContentProjectFile();
                file.Project = this;

                file.FileExtension = parentData.GetData<string>("ContentProjectFile.FileExtension" + i, index);
                file.Importer = parentData.GetData<string>("ContentProjectFile.Importer" + i, index);
                file.SaveOnEditorSave = parentData.GetData<bool>("ContentProjectFile.SaveOnEditorSave" + i, index);

                int importer = parentData.GetData<int>("ContentProjectFile.ImporterParameters" + i, index);
                if (importer > 0)
                {
                    file.ImporterParameters = new List<NameValue>();
                    for (int x = 0; x < importer; x++)
                    {
                        string name = parentData.GetData<string>("ContentProjectFile.ImporterParameter.Name" + i + ":" + x, index);
                        string valueS = parentData.GetData<string>("ContentProjectFile.ImporterParameter.Value" + i + ":" + x, index);
                        NameValue value = new NameValue(name, valueS);
                        file.ImporterParameters.Add(value);
                    }
                }

                file.NeedsProcessing = parentData.GetData<bool>("ContentProjectFile.NeedsProcessing" + i, index);
                file.Name = parentData.GetData<string>("ContentProjectFile.Name" + i, index);
                file.ProcessedPath = parentData.GetData<string>("ContentProjectFile.ProcessedPath" + i, index);
                file.Processor = parentData.GetData<string>("ContentProjectFile.Processor" + i, index);

                int processors = parentData.GetData<int>("ContentProjectFile.ProcessorParameters" + i, index);
                if (processors > 0)
                {
                    file.ProcessorParameters = new List<NameValue>();
                    for (int x = 0; x < processors; x++)
                    {
                        string name = parentData.GetData<string>("ContentProjectFile.ProcessorParameter.Name" + i + ":" + x, index);
                        string valueS = parentData.GetData<string>("ContentProjectFile.ProcessorParameter.Value" + i + ":" + x, index);
                        NameValue value = new NameValue(name, valueS);
                        file.ProcessorParameters.Add(value);
                    }
                }
                file.RelativePath = parentData.GetData<string>("ContentProjectFile.RelativePath" + i, index);

                this.Files.Add(file);
            }
        }
    }
}
